#ifndef MPHTTPCONFIG_H
#define MPHTTPCONFIG_H

/******************************
 *
 * 名   称：   HttpConfig 配置类
 * 用   途：   获取或设置Http相关的配置参数
 * 作用范围：   公共的
 * 创建时间：   2022-10-03
 * 备   注：   1. 采用单例模式实现
 *
 ******************************/

#include <cstddef>
#include <unordered_map>

#include "mpSingleton.h"
#include "mpUrl.h"
#include "mpHttpException.h"

namespace MP{
namespace HTTP{

class HttpConfig : public SingleTon<HttpConfig>
{
public:
    friend class SingleTon<HttpConfig>;
public:

    //设置建立HTTP连接的超时时间（单位：秒，默认值5）
    void set_http_connect_timeout(int sec){
        if(sec > 0){
            _http_connect_timeout = sec;
        }
    }
    int get_http_connect_timeout() const{
        return _http_connect_timeout;
    }

    //设置HTTP请求中写入data的超时时间（单位：秒，默认值20）
    void set_http_write_timeout(int sec){
        if(sec > 0){
            _http_write_timeout = sec;
        }
    }
    int get_http_write_timeout() const{
        return _http_write_timeout;
    }

    //设置HTTP请求中读取data的超时时间（单位：秒，默认值20）
    void set_http_read_timeout(int sec){
        if(sec > 0){
            _http_read_timeout = sec;
        }
    }
    int get_http_read_timeout() const{
        return _http_read_timeout;
    }

    //poll中允许活动的HttpConnection最大数量（默认值10）
    void set_pool_max_count_allocations(std::size_t value){
        if(value > 0){
            _pool_max_count_allocations = value;
        }
    }
    std::size_t get_pool_max_count_allocations() const{
        return _pool_max_count_allocations;
    }

    //poll中允许缓存的最大HTTP连接数量（默认值10）
    void set_pool_max_count_inpool(std::size_t value){
        _pool_max_count_inpool = value;
    }
    std::size_t get_pool_max_count_inpool() const{
        return _pool_max_count_inpool;
    }

    //poll中每个KEY允许缓存的最大HTTP连接数量（默认值3）
    void set_pool_max_count_preKey(std::size_t value){
        _pool_max_count_preKey = value;
    }
    std::size_t get_pool_max_count_preKey() const{
        return _pool_max_count_preKey;
    }

    //pool中Http连接缓存有效时间（秒）（默认值 20）
    void set_pool_max_cache_seconds(double value){
        if(value >= 0){
            _pool_max_cache_seconds = value;
        }
    }
    double get_pool_max_cache_seconds() const{
        return _pool_max_cache_seconds;
    }

    //pool中清理过期或者已关闭的Http连接的时间的最小间隔（秒）（默认值 60）
    void set_pool_min_interval_clean(double value){
        if(value>0){
            _pool_min_interval_clean = value;
        }
    }
    double get_pool_min_interval_clean() const{
        return _pool_min_interval_clean;
    }

    //注册HTTP CLIENT 缺省的URL地址
    void register_client_default_url(const std::string& name,
                                     const std::string & schema,
                                     const std::string & host,
                                     unsigned short port){

        if(name.empty())
        {
            return;
        }

        auto iter= _client_default_urls.find(name);
        if(iter ==_client_default_urls.end()){
            _client_default_urls.emplace(std::make_pair(std::string(name), Url(schema,host,port,"/")));
        }
        else{
            Url& url = iter->second;
            url.setScheme(schema);
            url.setHost(host);
            url.setPort(port);
            url.setRelativeUri("/");
        }
    }

    //获取HTTP CLIENT 缺省的URL地址
    void get_client_default_url(const std::string& name,
                               Url& url){

        if(name.empty()){
            url.setScheme("http");
            url.setHost("127.0.0.1");
            url.setPort(80);
            url.setRelativeUri("/");
        }

        auto iter= _client_default_urls.find(name);
        if(iter ==_client_default_urls.end()){
            throw HttpException("named '"+ name +"' http client unregistered");
        }


        Url& tmp = iter->second;

        url.setScheme(tmp.getScheme());
        url.setHost(tmp.getHost());
        url.setPort(tmp.getPort());
        url.setRelativeUri(tmp.getRelativeUri());
    }

protected:
    HttpConfig(){ }
private:
    int _http_connect_timeout = 5;
    int _http_write_timeout = 20;
    int _http_read_timeout = 20;

    std::size_t _pool_max_count_allocations = 10;                                        //poll中允许活动的HttpConnection最大数量
    std::size_t _pool_max_count_inpool = 10;                                             //poll中允许缓存的最大HTTP连接数量
    std::size_t _pool_max_count_preKey = 3;                                              //poll中每个KEY允许缓存的最大HTTP连接数量

    double _pool_max_cache_seconds = 20;                                                 //pool中Http连接缓存有效时间（秒）
    double _pool_min_interval_clean = 60;                                                //pool中清理过期或者已关闭的Http连接的时间的最小间隔（秒）

    std::unordered_map<std::string, Url> _client_default_urls;                           //HTTP CLIENT 缺省的URL地址

};

}   //HTTP
}   //MP

#endif // MPHTTPCONFIG_H
